package com.jeeplus.modules.common.excel.common.validator.impl;

import com.jeeplus.common.utils.StringUtil;
import com.jeeplus.modules.api.depart.entity.DepartManage;
import com.jeeplus.modules.api.depart.service.DepartManageService;
import com.jeeplus.modules.common.excel.common.anno.CollegeName;
import com.jeeplus.modules.common.excel.common.validator.abs.AbstractValidator;
import com.jeeplus.modules.common.utils.SpringBeanUtils;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 院系名称校验
 * @author wang.yishu
 */
public class CollegeNameValidator extends AbstractValidator {

    private final static String key = "collegeName";

    private CollegeName collegeName;
    //部门service
    private DepartManageService departManageService;

    @Override
    public boolean canValidate(Field field) {
        collegeName = field.getDeclaredAnnotation(CollegeName.class);
        return collegeName != null;
    }

    @Override
    public String toValidate(Object entity, Field field) {
        Map<String, List<Object>> necessaryValidateData = this.chain.getNecessaryValidateData();
        List<Object> necessaryData = null;
        if (!necessaryValidateData.containsKey(key)) {
            necessaryData = new ArrayList<>();
            departManageService = SpringBeanUtils.getBean(DepartManageService.class);
            DepartManage departManageParam = new DepartManage();
            departManageParam.setDepartmentType("1");//部门类型：1
            departManageParam.setState("1");//使用状态：1
            List<DepartManage> departManageList = departManageService.findList(departManageParam);
            if (departManageList != null && departManageList.size() > 0) necessaryData.addAll(departManageList);
            necessaryValidateData.put(key, necessaryData);
        } else {
            necessaryData = necessaryValidateData.get(key);
        }
        String transformTo = collegeName.transformTo();
        String forCodeFieldName = collegeName.forCode();
        String forCodeValue = "";
        if (entity == null) return null;
        field.setAccessible(true);
        try {
            Object value = field.get(entity);
            if (value == null) return null;
            if (value instanceof String) {
                String collegeNameStr = value.toString();
                if (StringUtil.isNotBlank(forCodeFieldName)) {
                    Field forCodeField = entity.getClass().getDeclaredField(forCodeFieldName);
                    forCodeField.setAccessible(true);
                    forCodeValue = (String) forCodeField.get(entity);
                }
                String finalForCodeValue = forCodeValue;
                List<Object> collect = necessaryData.stream().filter(obj -> ((DepartManage) obj).getName().equals(collegeNameStr) && (!StringUtil.isNotBlank(finalForCodeValue) || ((DepartManage) obj).getCode() == null || ((DepartManage) obj).getCode().equals("") || finalForCodeValue.equals(((DepartManage) obj).getCode()))).collect(Collectors.toList());
                if (collect.size() == 0) {
                    return collegeName.msg();
                } else {
                    if (StringUtil.isNotBlank(transformTo)) {
                        Field transformToField = entity.getClass().getDeclaredField(transformTo);
                        transformToField.setAccessible(true);
                        if (transformToField.getType().getName().equals(String.class.getName())) {
                            transformToField.set(entity, ((DepartManage)collect.get(0)).getId());
                        } else if(transformToField.getType().getName().equals(Integer.class.getName())){
                            transformToField.set(entity, Integer.valueOf(((DepartManage)collect.get(0)).getId()));
                        }
                    }
                }
            } else {
                return collegeName.msg();
            }
        } catch (IllegalAccessException | NoSuchFieldException e) {
            e.printStackTrace();
        }
        return null;
    }
}
